<template>
  <div @click="handleClick" v-bind="$attrs">
    <slot></slot>
  </div>
</template>

<script setup>
import { ref, onMounted, onUnmounted } from 'vue'

const emit = defineEmits(['animation-start', 'animation-end', 'click'])

const props = defineProps({
  // 动画类型：fade, scale, slide
  animationType: {
    type: String,
    default: 'fade',
    validator: (value) => ['fade', 'scale', 'slide'].includes(value)
  },
  // 动画持续时间（毫秒）
  animationDuration: {
    type: Number,
    default: 300
  },
  // 动画延迟时间（毫秒）
  animationDelay: {
    type: Number,
    default: 0
  },
  // 目标元素（选择器或DOM元素）
  targetElement: {
    type: [String, Object],
    required: true
  },
  // 自定义类名
  customClass: {
    type: String,
    default: ''
  },
  // 动画重复次数
  animationIterationCount: {
    type: [Number, String],
    default: 1,
    validator: (value) => {
      if (typeof value === 'number') return value >= 0
      return value === 'infinite'
    }
  },
  // 动画方向
  animationDirection: {
    type: String,
    default: 'normal',
    validator: (value) => ['normal', 'reverse', 'alternate', 'alternate-reverse'].includes(value)
  },
  // 是否禁用
  disabled: {
    type: Boolean,
    default: false
  }
})

// 目标元素引用
const targetEl = ref(null)

// 在组件挂载时获取目标元素
onMounted(() => {
  if (typeof props.targetElement === 'string') {
    targetEl.value = document.querySelector(props.targetElement)
  } else {
    targetEl.value = props.targetElement
  }

  if (!targetEl.value) {
    console.warn('ClickAnimations: Target element not found')
  }
})

// 处理点击事件
const handleClick = (e) => {
  if (props.disabled || !targetEl.value) return

  // 触发原生点击事件
  emit('click', e)

  // 清除旧动画
  targetEl.value.style.animation = ''
  void targetEl.value.offsetWidth // 触发重绘

  // 准备要添加的类名
  const classes = [`${props.animationType}-animation`]
  if (props.customClass) {
    classes.push(props.customClass)
  }

  // 应用动画样式
  targetEl.value.classList.add(...classes)
  targetEl.value.style.animationDuration = `${props.animationDuration}ms`
  targetEl.value.style.animationDelay = `${props.animationDelay}ms`
  targetEl.value.style.animationIterationCount = props.animationIterationCount
  targetEl.value.style.animationDirection = props.animationDirection

  // 处理动画开始事件
  const handleAnimationStart = (e) => {
    if (e.target === targetEl.value) {
      emit('animation-start', e)
    }
  }

  // 处理动画结束事件
  const handleAnimationEnd = (e) => {
    if (e.target === targetEl.value) {
      // 移除动画类和样式
      targetEl.value.classList.remove(...classes)
      targetEl.value.style.animation = ''
      emit('animation-end', e)
      removeListeners()
    }
  }

  // 移除事件监听器
  const removeListeners = () => {
    targetEl.value.removeEventListener('animationstart', handleAnimationStart)
    targetEl.value.removeEventListener('animationend', handleAnimationEnd)
  }

  // 添加事件监听器
  targetEl.value.addEventListener('animationstart', handleAnimationStart)
  targetEl.value.addEventListener('animationend', handleAnimationEnd)
}

// 组件卸载时清理
onUnmounted(() => {
  if (targetEl.value) {
    targetEl.value.style.animation = ''
    const animationClass = `${props.animationType}-animation`
    if (targetEl.value.classList.contains(animationClass)) {
      targetEl.value.classList.remove(animationClass)
    }
    if (props.customClass && targetEl.value.classList.contains(props.customClass)) {
      targetEl.value.classList.remove(props.customClass)
    }
  }
})
</script>

<style>
/* 渐变动画 */
.fade-animation {
  animation-name: fade;
}

@keyframes fade {
  0% { opacity: 1; }
  50% { opacity: 0.3; }
  100% { opacity: 1; }
}

/* 缩放动画 */
.scale-animation {
  animation-name: scale;
}

@keyframes scale {
  0% { transform: scale(1); }
  50% { transform: scale(1.2); }
  100% { transform: scale(1); }
}

/* 滑动动画 */
.slide-animation {
  animation-name: slide;
}

@keyframes slide {
  0% { transform: translateX(0); }
  25% { transform: translateX(10px); }
  75% { transform: translateX(-10px); }
  100% { transform: translateX(0); }
}

/* Webkit 浏览器兼容性 */
@-webkit-keyframes fade {
  0% { opacity: 1; }
  50% { opacity: 0.3; }
  100% { opacity: 1; }
}

@-webkit-keyframes scale {
  0% { transform: scale(1); }
  50% { transform: scale(1.2); }
  100% { transform: scale(1); }
}

@-webkit-keyframes slide {
  0% { transform: translateX(0); }
  25% { transform: translateX(10px); }
  75% { transform: translateX(-10px); }
  100% { transform: translateX(0); }
}

/* Firefox 浏览器兼容性 */
@-moz-keyframes fade {
  0% { opacity: 1; }
  50% { opacity: 0.3; }
  100% { opacity: 1; }
}

@-moz-keyframes scale {
  0% { transform: scale(1); }
  50% { transform: scale(1.2); }
  100% { transform: scale(1); }
}

@-moz-keyframes slide {
  0% { transform: translateX(0); }
  25% { transform: translateX(10px); }
  75% { transform: translateX(-10px); }
  100% { transform: translateX(0); }
}
</style>